/*
clsquare - closed loop simulation system
Copyright (c) 2004, Neuroinformatics Group, Prof. Dr. Martin Riedmiller,
University of Osnabrueck

Author: Martin Riedmiller

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

   * Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
   * Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
     distribution.
   * Neither the name of the <ORGANIZATION> nor the names of its
     contributors may be used to endorse or promote products derived
     from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE. 
*/

#ifndef _OUTPUT_H_
#define _OUTPUT_H_

#include "gplot.h"
#include "global.h"

/**
 * Output on file
 */
class Output
{
 public:
   /** Outputs current state transition
   * \param state: current state. 
   * \param observation: observation of current state. 
   * \param referece_input: reference_input of plant
   * \param action: executed action in current state.
   * \param reward: reward for executing action in current state
   * \param cycle_ctr: control cycle in current episode.
   * \param episode: current episode
   * \param total_time: elapsed time since start of simulation loop.
   * \param episode_time: elapsed time since start of current episode
   * \param total_num_of_cycles: number of control cycles since start of simulation loop.
   * \return true, for success. */
  bool notify(const double *state, const double *observation, const double *reference_input, 	
	      const double *action, const double reward, const long cycle, const long episode, const double total_time, 
	      const double episode_time, const long total_num_of_cycles);

   /** Initializes output module.
   * \param _state_dim: dimension of plant state
   * \param _observation_dim: dimension of observation 
   * \param _action_dim: dimension of action space.
   * \param _reference_input_dim: dimension of reference input
   * \param delta_t: duration of one control cycle.
   * \param fname: file, which contains conifiguration
   * \return true, for success. */ 
  bool init(int _state_dim, int _observation_dim, int _action_dim, int _reference_input_dim, double _delta_t, const char *fname=0);

  /** Terminate graphics.
   * \return true for success */
  bool deinit(); 
  
 protected:
  /** outputs previous state transition (one cycle before).
   * \param _out: output stream
   * \param _prev_observation: previous observation (one cycle before)
   * \param _prev_action: action executed on cycle before
   * \param prev_reward: previous reward (one cycle before)
   * \param observation: observation of current state */
  void write_om0(std::ostream& _out, const double* _prev_observation, const double* _prev_action,  const double _reward, const double* _observation);

  /** outputs current state transition.
   * \param _out: output stream
   * \param _state: current state
   * \param _observation: observation of current state 
   * \param _action: action executed in current state
   * \param _reward: reward for executing action in current state
   * \param _reference_input: reference input for current state */
  void write_om1(std::ostream& _out, const double* _state, const double* _observation, const double* _action, const double _reward, const double* _reference_input);
  
  /** outputs an observation.
   * \param _out: output stream
   * \param observation: observation */
  void print_observation(std::ostream& _out, const double* _observation);

  /** outputs an action.
   * \param _out: output stream
   * \param action: action */
  void print_action(std::ostream& _out, const double* _action);

  /** outputs a reward
   * \param _out: output stream
   * \param reward: reward */
  void print_reward(std::ostream& _out, const double reward);

   /** outputs a state.
   * \param _out: output stream
   * \param _state: state */
  void print_state(std::ostream& _out, const double* _state);
  
   /** outputs a reference input.
   * \param _out: output stream
   * \param _reference_input: reference input */
  void print_reference_input(std::ostream& _out, const double* _reference_input);

   /** outputs information about the current control cycle within the episode.       
   * \param _out: output stream
   * \param cycle: current control cycle of episode
   * \param episode_time: time elapsed since start of the episode 
   * \param total_time: time elapsed since start of the simulation loop */
  void print_cycle_info(std::ostream& _out, long int cycle, double episode_time, double total_time);

  /** print overall header of output module. 
   * \param _out: output stream  */
  void print_header(std::ostream& _out);

  /** print header for an episode.
   * \param out: output stream
   * \param episode : number of episode */
  void print_episode_header(std::ostream& _out, long int _episode);

  int      state_dim; // dimension of state spac e
  int      action_dim; // dimension of action space
  int      observation_dim; // dimension of observation space
  int      reference_input_dim; // dimension of reference inputs
  double   delta_t; // time between to control cycles [s]


  std::vector< int > reduce_state_ids; // selected dimension of system states
  std::vector< int > reduce_observation_ids; // selected dimensions of observations
  std::vector< int > reduce_action_ids; // selected dimensions of actions
  std::vector< int > reduce_reference_input_ids; // selected dimensions of reference inputs

  timeval  start_tval; // starting time of making outputs
  double  *prev_observation; // previous observation
  double  *prev_action; // previous action
  double prev_reward; // previous reward

  std::ostream  *out; // output stream
  int  outp_width, outp_prec; // formatting constants
  char ProtFName[MAX_STR_LEN]; // name of configuration file
  int  output_mode; // output mode (with or without reference inputs)
 
  /** reads options of output module.
   * \param fname: name of configuration file */
  bool read_options(const char * fname);
};



#endif

